// ============================================
// internal/client/api_client.go
// ============================================

package client

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"

	"github.com/sirupsen/logrus"
)

type APIClient struct {
	baseURL    string
	httpClient *http.Client
	logger     *logrus.Logger
}

func (c *APIClient) GetServerURL() string {
	return c.baseURL
}

func NewAPIClient(baseURL string, logger *logrus.Logger) *APIClient {
	return &APIClient{
		baseURL: baseURL,
		httpClient: &http.Client{
			Timeout: 30 * time.Second,
		},
		logger: logger,
	}
}

// Request 通用请求方法
func (c *APIClient) Request(ctx context.Context, method, path string, body interface{}) ([]byte, error) {
	var reqBody io.Reader
	if body != nil {
		jsonData, err := json.Marshal(body)
		if err != nil {
			return nil, fmt.Errorf("failed to marshal request: %w", err)
		}
		reqBody = bytes.NewBuffer(jsonData)
	}

	url := c.baseURL + path
	req, err := http.NewRequestWithContext(ctx, method, url, reqBody)
	if err != nil {
		return nil, fmt.Errorf("failed to create request: %w", err)
	}

	req.Header.Set("Content-Type", "application/json")

	c.logger.WithFields(logrus.Fields{
		"method": method,
		"url":    url,
	}).Debug("API request")

	resp, err := c.httpClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("request failed: %w", err)
	}
	defer resp.Body.Close()

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("failed to read response: %w", err)
	}

	if resp.StatusCode >= 400 {
		return nil, fmt.Errorf("API error (status %d): %s", resp.StatusCode, string(respBody))
	}

	return respBody, nil
}

// Get 发送 GET 请求
func (c *APIClient) Get(ctx context.Context, path string) ([]byte, error) {
	return c.Request(ctx, "GET", path, nil)
}

// Post 发送 POST 请求
func (c *APIClient) Post(ctx context.Context, path string, body interface{}) ([]byte, error) {
	return c.Request(ctx, "POST", path, body)
}

// Delete 发送 DELETE 请求
func (c *APIClient) Delete(ctx context.Context, path string) ([]byte, error) {
	return c.Request(ctx, "DELETE", path, nil)
}

// Patch 发送 PATCH 请求
func (c *APIClient) Patch(ctx context.Context, path string, body interface{}) ([]byte, error) {
	return c.Request(ctx, "PATCH", path, body)
}
